﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using AzukiMap.MapSource;
using AzukiMap.Map;
using Geotools.Geometries;
using AzukiMap.Tools;

namespace AzukiMapUI
{
	public partial class ImageSourceProperties : UserControl, IMapSourceProperties
	{
        RasterFileSource _imageSource;
        GeometryUtil _geomUtil;

        public RasterFileSource RasterSource
        {
            set
            {
                _imageSource = value;
                SetForm();
            }
            get
            {
                SetAll();
                return _imageSource;
            }
        }

        public MapSource MapDataSource
        {
            get
            {
                SetAll();
                return _imageSource;
            }
        }

		public ImageSourceProperties()
		{
			// Required to initialize variables
			InitializeComponent();
            _imageSource = new RasterFileSource();
            _geomUtil = new GeometryUtil();

            SetForm();
            CheckAllFormData();
		}

        void SetForm()
        {
            if (_imageSource.ImageUri != null)
            {
                FormInputControl.SetForm(TbUri, _imageSource.ImageUri.ToString());
            }
            else
            {
                TbUri.Text = "";
            }
            if (_imageSource.MaxExtent != null)
            {
                /*
                GTCoordinate trPoint = _geomUtil.GetExtentPoint(_imageSource.MaxExtent, ExtentOrder.TOP_RIGHT);
                GTCoordinate blPoint = _geomUtil.GetExtentPoint(_imageSource.MaxExtent, ExtentOrder.BOTTOM_LEFT);

                double maxLon = trPoint.X;
                double maxLat = trPoint.Y;
                double minLon = blPoint.X;
                double minLat = blPoint.Y;

                FormInputControl.SetForm(TbMaxLon, maxLon);
                FormInputControl.SetForm(TbMaxLat, maxLat);
                FormInputControl.SetForm(TbMinLon, minLon);
                FormInputControl.SetForm(TbMinLat, minLat);
                 */
                FormInputControl.SetForm(TbMaxLon, _imageSource.MaxExtent.MaxX);
                FormInputControl.SetForm(TbMaxLat, _imageSource.MaxExtent.MaxY);
                FormInputControl.SetForm(TbMinLon, _imageSource.MaxExtent.MinX);
                FormInputControl.SetForm(TbMinLat, _imageSource.MaxExtent.MinY);
            }
            else
            {
                TbMaxLon.Text = "";
                TbMaxLat.Text = "";
                TbMinLon.Text = "";
                TbMinLat.Text = "";
            }
            FormInputControl.SetForm(TbSrid, _imageSource.Srid);
            FormInputControl.SetForm(TbMaxScale, _imageSource.MaxScale);
            FormInputControl.SetForm(TbMinScale, _imageSource.MinScale);
            FormInputControl.SetForm(TbWidth, _imageSource.Width);
            FormInputControl.SetForm(TbHeight, _imageSource.Height);
        }

        void SetAll()
        {
            SetUri();
            SetExtent();
            SetScales();
            SetSize();
        }

        void SetUri()
        {
            if (CheckUri())
                _imageSource.ImageUri = new Uri(TbUri.Text);
        }

        void SetExtent()
        {
            if (CheckMinMaxPoint())
            {
                string maxLonStr = TbMaxLon.Text;
                string maxLatStr = TbMaxLat.Text;
                string minLonStr = TbMinLon.Text;
                string minLatStr = TbMinLat.Text;
                double maxLon = double.Parse(maxLonStr);
                double maxLat = double.Parse(maxLatStr);
                double minLon = double.Parse(minLonStr);
                double minLat = double.Parse(minLatStr);

                //_imageSource.MaxExtent = _geomUtil.CreateExtentPolygon(minLon, minLat, maxLon, maxLat);
                _imageSource.MaxExtent = new GTEnvelope(minLon, minLat, maxLon, maxLat);
            }
        }

        void SetScales()
        {
            if (CheckMinMaxScale())
            {
                _imageSource.MinScale = double.Parse(TbMinScale.Text);
                _imageSource.MaxScale = double.Parse(TbMaxScale.Text);
            }
        }

        void SetSize()
        {
            if (CheckWidth() && CheckHeight())
            {
                _imageSource.Width = int.Parse(TbWidth.Text);
                _imageSource.Height = int.Parse(TbHeight.Text);
            }
        }

        public bool CheckAllFormData()
        {
            bool isOk1 = CheckUri();
            bool isOk2 = CheckMinMaxPoint();
            bool isOk3 = CheckMinMaxScale();
            bool isOk4 = CheckSrid();
            bool isOk5 = CheckWidth();
            bool isOk6 = CheckHeight();

            return (isOk1 && isOk2 && isOk3 && isOk4 && isOk5 && isOk6);
        }

        bool CheckUri()
        {
            string inputStr = TbUri.Text;
            return FormInputControl.CheckUri(inputStr, IconErrorUri);
        }

        bool CheckMaxPointDouble()
        {
            string maxLonStr = TbMaxLon.Text;
            string maxLatStr = TbMaxLat.Text;
            bool isLonDouble = FormInputControl.DoubleStringChecker(maxLonStr);
            bool isLatDouble = FormInputControl.DoubleStringChecker(maxLatStr);
            if (isLonDouble && isLatDouble)
            {
                FormInputControl.HideElement(IconErrorMaxPoint);
                return true;
            }
            else
            {
                FormInputControl.ShowElement(IconErrorMaxPoint);
                return false;
            }
        }

        bool CheckMinPointDouble()
        {
            string minLonStr = TbMinLon.Text;
            string minLatStr = TbMinLat.Text;
            bool isLonDouble = FormInputControl.DoubleStringChecker(minLonStr);
            bool isLatDouble = FormInputControl.DoubleStringChecker(minLatStr);
            if (isLonDouble && isLatDouble)
            {
                FormInputControl.HideElement(IconErrorMinPoint);
                return true;
            }
            else
            {
                FormInputControl.ShowElement(IconErrorMinPoint);
                return false;
            }
        }

        bool CheckMinMaxPoint()
        {
            if (CheckMaxPointDouble() && CheckMinPointDouble())
            {
                string maxLonStr = TbMaxLon.Text;
                string maxLatStr = TbMaxLat.Text;
                string minLonStr = TbMinLon.Text;
                string minLatStr = TbMinLat.Text;
                double maxLon = double.Parse(maxLonStr);
                double maxLat = double.Parse(maxLatStr);
                double minLon = double.Parse(minLonStr);
                double minLat = double.Parse(minLatStr);

                if (maxLon > minLon && maxLat > minLat)
                {
                    return true;
                }
                else
                {
                    FormInputControl.ShowElement(IconErrorMaxPoint);
                    FormInputControl.ShowElement(IconErrorMinPoint);
                    return false;
                }
            }
            else
            {
                return false;
            }
        }

        bool CheckWidth()
        {
            string inputStr = TbWidth.Text;
            return FormInputControl.CheckNaturalNumber(inputStr, IconErrorWidth);
        }

        bool CheckHeight()
        {
            string inputStr = TbHeight.Text;
            return FormInputControl.CheckNaturalNumber(inputStr, IconErrorHeight);
        }

        bool CheckSrid()
        {
            string inputStr = TbSrid.Text;
            return FormInputControl.CheckNaturalNumber(inputStr, IconErrorSrid);
        }

        bool CheckMaxScaleDouble()
        {
            string inputStr = TbMaxScale.Text;
            return FormInputControl.CheckPositiveDouble(inputStr, IconErrorMaxScale);
        }

        bool CheckMinScaleDouble()
        {
            string inputStr = TbMinScale.Text;
            return FormInputControl.CheckPositiveDouble(inputStr, IconErrorMinScale, true);
        }

        bool CheckMinMaxScale()
        {
            bool isMaxDouble = CheckMaxScaleDouble();
            bool isMinDouble = CheckMinScaleDouble();
            //if (CheckMinScaleDouble() && CheckMaxScaleDouble())
            if ( isMaxDouble && isMinDouble)
            {
                double maxScale = double.Parse(TbMaxScale.Text);
                double minScale = double.Parse(TbMinScale.Text);
                if (maxScale > minScale)
                {
                    return true;
                }
                else
                {
                    FormInputControl.ShowElement(IconErrorMaxScale);
                    FormInputControl.ShowElement(IconErrorMinScale);
                    return false;
                }
            }
            else
            {
                return false;
            }
        }


        void TbUri_LostFocus(object sender, RoutedEventArgs e)
        {
            CheckUri();
        }

        void TbMaxLon_LostFocus(object sender, RoutedEventArgs e)
        {
            CheckMinMaxPoint();
        }

        void TbMaxLat_LostFocus(object sender, RoutedEventArgs e)
        {
            CheckMinMaxPoint();
        }

        void TbMinLon_LostFocus(object sender, RoutedEventArgs e)
        {
            CheckMinMaxPoint();
        }

        void TbMinLat_LostFocus(object sender, RoutedEventArgs e)
        {
            CheckMinMaxPoint();
        }

        void TbSrid_LostFocus(object sender, RoutedEventArgs e)
        {
            CheckSrid();
        }

        void TbMaxScale_LostFocus(object sender, RoutedEventArgs e)
        {
            CheckMinMaxScale();
        }

        void TbMinScale_LostFocus(object sender, RoutedEventArgs e)
        {
            CheckMinMaxScale();
        }

        void BtnTest_Click(object sender, RoutedEventArgs e)
        {

        }

        void TbWidth_LostFocus(object sender, RoutedEventArgs e)
        {
            CheckWidth();
        }

        void TbHeight_LostFocus(object sender, RoutedEventArgs e)
        {
            CheckHeight();
        }

        void TbOptionParams_LostFocus(object sender, RoutedEventArgs e)
        {
        }
    }
}